﻿using System;
using System.Web;
using System.Xml;
using System.Collections.Specialized;
using SyCODE.Component.DataFactory;
using System.IO;
using SyCODE.Component;

namespace SyCODE.Blog.TrackBack
{
    /// <summary>
    /// TrackBack 事件处理程序
    /// </summary>
    public class Handler : IHttpHandler
    {
        #region IHttpHandler 成员
        /// <summary>
        /// 输出异常信息节点
        /// </summary>
        /// <param name="writer">只进方式编写器</param>
        private void WriteOkMessage(XmlTextWriter writer)
        {
            writer.WriteStartElement("error");
            writer.WriteValue(0);
            writer.WriteEndElement();
        }
        /// <summary>
        /// 输出异常信息节点
        /// </summary>
        /// <param name="writer">只进方式编写器</param>
        /// <param name="message">异常信息</param>
        private void WriteErrorMessage(XmlTextWriter writer, string message)
        {
            writer.WriteStartElement("error");
            writer.WriteValue(1);
            writer.WriteEndElement();

            writer.WriteStartElement("message");
            writer.WriteString(message);
            writer.WriteEndElement();
        }

        /// <summary>
        /// 摘要:
        ///     获取一个值，该值指示其他请求是否可以使用 System.Web.IHttpHandler 实例。
        ///
        /// 返回结果:
        ///     如果 System.Web.IHttpHandler 实例可再次使用，则为 true；否则为 false。
        /// </summary>
        public bool IsReusable
        {
            get
            {
                return true;
            }
        }

        /// <summary>
        /// 摘要:
        ///     启用 HTTP Web 请求的处理程序。
        ///
        /// 参数:
        ///   context:
        ///     System.Web.HttpContext 对象，它提供对用于为 HTTP 请求提供服务的内部服务器对象（如 Request、Response、Session
        ///     和 Server）的引用。
        /// </summary>
        /// <param name="context">HTTP信息封装</param>
        public void ProcessRequest(HttpContext context)
        {
            string topic = context.Request.QueryString["id"];
            if (!String.IsNullOrEmpty(topic))
            {
                XmlTextWriter writer = new XmlTextWriter(context.Response.OutputStream, context.Response.ContentEncoding);
                writer.WriteStartDocument();
                writer.WriteStartElement("response");

                NameValueCollection nvc = new NameValueCollection(context.Request.Form);

                string url = nvc["url"];
                if (!String.IsNullOrEmpty(url))
                {
                    nvc.Add("topic", topic);
                    string u = context.Request.QueryString["u"];
                    XmlDocument tbdom = new XmlDocument();
                    string path = Path.Combine(AppPath.GetUserPhysicalPath(u), @"topic\" + topic + @"\trackback.xml");
                    if (File.Exists(path))
                    {
                        tbdom.Load(path);
                    }
                    else
                    {
                        tbdom.LoadXml("<?xml version=\"1.0\" encoding=\"utf-8\" ?><?xml-stylesheet type=\"text/xsl\" href=\"/ui/common/container.xsl\"?><html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /><title>" + u + "-topic-" + topic + "-trackback - Powered By X3BLOG</title></head><body /></html>");
                    }

                    XmlNode body = tbdom.DocumentElement.SelectSingleNode("body");
                    XmlElement tb = (XmlElement)body.SelectSingleNode("p[a/@href=\"" + url.Replace("\"", "&quot;") + "\"]");

                    if (tb == null)
                    {
                        DBAM dbam = new DBAM();
                        try
                        {
                            tb = tbdom.CreateElement("p");
                            tb.SetAttribute("time", DateTime.Now.ToString(StringResource.GetField("datetimeformat")));

                            XmlElement link = tbdom.CreateElement("a");
                            link.SetAttribute("href", url);
                            link.SetAttribute("title", nvc["blog_name"]);
                            link.InnerText = nvc["title"];
                            tb.AppendChild(link);

                            XmlElement excerpt = tbdom.CreateElement("pre");
                            excerpt.InnerText = nvc["excerpt"];
                            tb.AppendChild(excerpt);

                            body.AppendChild(tb);

                            if (body.ChildNodes.Count > 30)
                            {
                                body.RemoveChild(body.FirstChild);
                            }

                            tbdom.Save(path);

                            dbam.BuildParameters("trackback", nvc);
                            if (dbam.Execute() > 0)
                            {
                                WriteOkMessage(writer);
                            }
                            else
                            {
                                WriteErrorMessage(writer, "Invalid blog item referred.");
                            }
                        }
                        catch (Exception ex)
                        {
                            WriteErrorMessage(writer, ex.Message);
                        }
                        finally
                        {
                            dbam.Dispose();
                        }
                    }
                    else
                    {
                        try
                        {
                            tb.SetAttribute("time", DateTime.Now.ToString(StringResource.GetField("datetimeformat")));
                            tb.FirstChild.Attributes["title"].Value = nvc["blog_name"];
                            tb.FirstChild.InnerText = nvc["title"];
                            tb.LastChild.InnerText = nvc["excerpt"];

                            tbdom.Save(path);
                        }
                        finally
                        {
                            WriteOkMessage(writer);
                        }
                    }
                }
                else
                {
                    WriteErrorMessage(writer, @"The url not specified in the POST request.");
                }
                writer.WriteEndElement();
                writer.WriteEndDocument();
                writer.Flush();
            }
        }

        #endregion
    }
}